package com.stm.bi.etl.prod;

import com.stm.bi.core.util.DateUtils;
import com.stm.bi.core.util.ETLUtils;
import com.stm.bi.dto.query.ods.OdsListQry;
import com.stm.bi.enums.DateType;
import com.stm.bi.etl.AbstractDataEtlTask;
import com.stm.bi.repository.dataobject.ods.OdsWarehouseDO;
import com.stm.bi.repository.ods.OdsWarehouseRepository;
import com.stm.framework.core.util.FileResourceLoader;
import com.stm.framework.dto.Response;
import com.stm.ucenter.api.DeptRemoteService;
import com.stm.ucenter.dto.query.org.DeptListQry;
import com.stm.ucenter.dto.vo.org.DeptVO;
import jakarta.annotation.Resource;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;

public abstract class AbsProdEtlTask extends AbstractDataEtlTask {

    @Resource
    protected OdsWarehouseRepository odsWarehouseRepository;

    @Resource
    protected DeptRemoteService deptRemoteService;

    @Override
    public boolean isTenantLine() {
        return true;
    }

    @Override
    public boolean syncWithTimeRange() {
        return true;
    }


    @Override
    public int getDelayDays() {
        return 0;
    }


    public abstract String getGroupField();

    public abstract String getSelectSql();

    public abstract String getSelectBeforeDataSql();

//    public abstract String getInventSql();

    @Override
    public List<DateType> getEtlDateTypes() {
        return Arrays.asList(DateType.YEAR, DateType.MONTH, DateType.WEEK, DateType.DAY);
    }

    @Override
    public List<Map> extract(Long orgId, String orgNo, DateType dateType, LocalDateTime startDateTime, LocalDateTime endDateTime) {

        String selectSql = FileResourceLoader.getResourceAsString(getSelectSql());
        String selectAllSql = FileResourceLoader.getResourceAsString(getSelectBeforeDataSql());
        String endDate = DateUtils.getDateStrByDateType(endDateTime, dateType);
        List<String> etlDateList = DateUtils.getETLDateList(startDateTime, endDateTime, dateType);

        List<Map> beforeData = jdbcService.selectList(selectAllSql, new Object[]{dateType.getValue(), orgNo, endDate});

        List<Map> data = new ArrayList<>();
        for(String date: etlDateList){
            List<Map> maps = jdbcService.selectList(selectSql, new Object[]{dateType.getValue(), orgNo, date});

            maps.forEach(m -> {

                BigDecimal qty = m.get("qty") != null ? (BigDecimal) m.get("qty") : BigDecimal.ZERO;
                if(qty.doubleValue() != 0){
                    m.put("price_avg",m.get("sales_amount") != null ? ((BigDecimal) m.get("sales_amount")).divide(qty , 2, RoundingMode.HALF_UP) : BigDecimal.ZERO);
                }

                List<Map> collect = beforeData.stream()
                        .filter(b -> Objects.equals(b.get("dept_id"), m.get("dept_id"))
                                && Objects.equals(b.get("sales_type"), m.get("sales_type"))
                                && Objects.equals(b.get("prod_season"), m.get("prod_season"))
                                && Objects.equals(b.get("return_season"), m.get("return_season"))
                                && Objects.equals(b.get(getGroupField()), m.get(getGroupField()))
                                && ((String) b.get("date")).compareTo((String) m.get("date")) <= 0)
                        .toList();

                if(!collect.isEmpty()){
                    m.put("cumulative_qty", collect.stream().map(b -> (BigDecimal) b.get("qty")).reduce(BigDecimal.ZERO, BigDecimal::add));
                }

            });
            data.addAll(maps);
        }

        return data;

    }

    private Map<Long, Long> getDeptIdMap(Long orgId, String orgNo) {
        //仓库与部门的对应关系逻辑
        Response<List<DeptVO>> deptResp = deptRemoteService.selectList(new DeptListQry().setOrgId(orgId));
        if(!deptResp.isSuccess()){
            log.error("部门查询失败:{}", deptResp.getMessage());
            return new HashMap<>();
        }

        List<DeptVO> depts = deptResp.getData();
        Map<Long, Long> deptMap = new HashMap<>();
        depts.forEach(d -> deptMap.put(d.getId(), d.getParentId()));

        List<OdsWarehouseDO> warehouses = odsWarehouseRepository.selectList(new OdsListQry().setOrgNo(orgNo));
        List<Long> deptIds = warehouses.stream().map(OdsWarehouseDO::getDeptId).distinct().filter(Objects::nonNull).toList();

        //获取对应的仓库部门对应关系MAP
        return ETLUtils.getWarehouseDeptIdMap(deptMap, deptIds);
    }

}
